home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Textfiles / MacSerialSoftware.txt < prev    next >
Text File  |  1997-01-04  |  6KB  |  225 lines

  1. This is a mini-lecture on writing C programs to use the Serial Driver to
  2. send and receive using the Macintosh serial port. If at all possible, try to
  3. use the Serial Driver rather than talking directly to the hardware. It will
  4. make life simpler. To illustrate the techniques I am using a simple program
  5. I wrote some years ago when I was playing around with hardware and software
  6. handshaking. The complete program is included at the end of this page.
  7.  
  8. Opening the serial port
  9.  
  10. You have to open the output channel, then the input channel, using
  11. OpenDriver.
  12.  
  13. status = OpenDriver("\p.AOut",&outchan);
  14. status = OpenDriver("\p.AIn",&inchan);
  15.  
  16. This opens the modem port, if you want to open the printer port substitute
  17. the names ".BOut" and ".BIn" instead.
  18.  
  19. Writing to the serial port
  20.  
  21. Writing is very simple, you tell it how many bytes to write and where the
  22. bytes are. The only weirdness is that the "count" parameter is passed as
  23. reference, so it cannot be a literal number. You have to make a "long"
  24. variable and store into it. This example writes one character.
  25.  
  26. buff[0] = achar;
  27. count = 1;
  28. status = FSWrite(aoutRefNum,&count,buff);
  29.  
  30. This example writes a bunch of characters.
  31.  
  32. BlockMove("abcdefghijklmnopqrstuvwxyz\r\n",buff,28);
  33. count = 28;
  34. status = FSWrite(aoutRefNum,&count,buff);
  35.  
  36. Reading from the serial port
  37.  
  38. If you try to blindly read from the serial port, the Macintosh will hang,
  39. doing nothing, until those characters are received. To do a non-blocking
  40. read you should use the SerGetBuf() function, which returns the number of
  41. characters available to be read. This is an interesting coding sequence for
  42. processing one character at a time.
  43.  
  44. status = SerGetBuf(ainRefNum,&count);
  45. if (0 == count)
  46.     break;
  47. count = 1;
  48. status = FSRead(ainRefNum,&count,cbuff);
  49. ch = 0x7F & cbuff[0];
  50.  
  51. The SerGetBuf routine returns the actual number of characters in the read
  52. buffer, but we only read one of them at a time. Then we strip off the parity
  53. bit by ANDing with 0x7F.
  54.  
  55. Changing the settings
  56.  
  57. Here is an example for turning on hardware or software handshaking
  58.  
  59. SerShk sconf;
  60. /* xonoff */
  61.     sconf.fXOn = 1;
  62.     sconf.fInX = 1;
  63.     sconf.xOn = 17;
  64.     sconf.xOff = 19;
  65.  
  66. /* hardware
  67.     sconf.fCTS = 1;
  68.     sconf.fDTR = 1;
  69. */
  70. status = SerHShake(aoutRefNum,&sconf);
  71.  
  72. [Note: Inside Macintosh: Devices claims that SerHShake does not honor the
  73. fDTR flag and that you have to use a low-level CSCODE=14 call to make the
  74. driver change its DTR flow control enable state. I did not run into this
  75. during testing, but I will test it when I get a chance. If this turns out to
  76. be the case I guess I will have to update this example... -zben 7/12/95]
  77.  
  78. Here is an example for setting the baud rate, parity, etc.
  79.  
  80. status = SerReset(aoutRefNum,baud1200|stop10|noParity|data8);
  81.  
  82. Example Program
  83.  
  84. #include <devices.h>
  85. #include <files.h>
  86. #include <fonts.h>
  87. #include <memory.h>
  88. #include <menus.h>
  89. #include <packages.h>
  90. #include <serial.h>
  91. #include <types.h>
  92. #include <windows.h>
  93.  
  94. WindowPtr windp;
  95. EventRecord myevent;
  96. SerShk sconf;
  97.  
  98. main()
  99. {
  100.     short status, inchan, outchan;
  101.     Rect bounds;
  102.     char buff[256];
  103.  
  104.     InitGraf( (Ptr) &qd.thePort );
  105.     InitFonts();
  106.     InitWindows();
  107.     InitMenus();
  108.     TEInit();
  109.     InitDialogs(nil);
  110.     InitCursor();
  111.  
  112. /* xonoff */
  113.     sconf.fXOn = 1;
  114.     sconf.fInX = 1;
  115.     sconf.xOn = 17;
  116.     sconf.xOff = 19;
  117.  
  118. /* hardware
  119.     sconf.fCTS = 1;
  120.     sconf.fDTR = 1;
  121. */
  122.     if (noErr != (status=OpenDriver("\p.AOut",&outchan)) ) {
  123.         NumToString(status,buff);
  124.         DebugStr(buff);
  125.         ExitToShell();
  126.     }
  127.     if (noErr != (status=OpenDriver("\p.AIn",&inchan)) ) {
  128.         NumToString(status,buff);
  129.         DebugStr(buff);
  130.         ExitToShell();
  131.     }
  132.  
  133.     if (noErr != (status=SerHShake(aoutRefNum,&sconf)) ) {
  134.         NumToString(status,buff);
  135.         DebugStr(buff);
  136.         ExitToShell();
  137.     }
  138.  
  139.     SetRect(&bounds,100,100,300,300);
  140.     windp = NewWindow(nil,&bounds,"\pserial",true,documentProc,
  141.         (WindowPtr)-1, true, 0);
  142.     SetPort(windp);
  143.     MoveTo(10,180);
  144.  
  145.     do {
  146.         if ( WaitNextEvent(everyEvent,&myevent,2,nil) )
  147.             if (keyDown == myevent.what) {
  148.                 status = myevent.message & 0x7F;
  149.                 if (3 == status)
  150.                     muchout();
  151.                 else if ('\b' == status)
  152.                     ExitToShell();
  153.                 else
  154.                     sendchar(status);
  155.             }
  156.         harvest();
  157.     } while (true);
  158. }
  159.  
  160. harvest()
  161. {
  162.     short status;
  163.     int count;
  164.     char ch;
  165.     char cbuff[10];
  166.     char buff[256];
  167.     RgnHandle xrgn;
  168.  
  169.     do {
  170.         if (noErr != (status=SerGetBuf(ainRefNum,&count)) ) {
  171.             NumToString(status,buff);
  172.             DebugStr(buff);
  173.             ExitToShell();
  174.         }
  175.         if (0 == count)
  176.             break;
  177.         count = 1;
  178.         FSRead(ainRefNum,&count,cbuff);
  179.         ch = 0x7F & cbuff[0];
  180.         if ('\n' == ch) {
  181.             xrgn = NewRgn();
  182.             ScrollRect(&windp->portRect,0,-10,xrgn);
  183.             DisposeRgn(xrgn);
  184.             MoveTo(10,180);
  185.         } else
  186.             DrawChar(ch);
  187.    } while (1);
  188. }
  189.  
  190. sendchar(int achar)
  191. {
  192.     short status;
  193.     int count;
  194.     char buff[256];
  195.  
  196.     buff[0] = achar;
  197.     count = 1;
  198.     if (noErr != (status=FSWrite(aoutRefNum,&count,buff)) ) {
  199.         NumToString(status,buff);
  200.         DebugStr(buff);
  201.     }
  202. }
  203.  
  204. muchout()
  205. {
  206.     short contl, status;
  207.     int count;
  208.     char buff[256];
  209.  
  210.     BlockMove("abcdefghijklmnopqrstuvwxyz\r\n",buff,28);
  211.     for (contl=0; contl<1000; contl++) {
  212.         count = 28;
  213.         if (noErr != (status=FSWrite(aoutRefNum,&count,buff)) ) {
  214.             NumToString(status,buff);
  215.             DebugStr(buff);
  216.             contl = 1000;
  217.         }
  218.     }
  219. }
  220.  
  221. You might find more interesting information in Macintosh Technical Notes
  222. HW4, HW545, DV11, DV16, and DV555.
  223. ----------------------------------------------------------------------------
  224. Back to ZBEN's home page.
  225.